package czy.demo.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @PreAuthorize注解在方法调用之前，根据表达式计算结果限制访问
 * spel表达式功能强大，可以实现各种逻辑运算，并且获取方法参数、返回值等
 * 基本上是功能最完整的方法安全注解
 */
@RestController
@RequestMapping("/pre")
public class PreController {

    /**
     * 使用anonymous表达式时，不需要()
     * 如果带上括号，会出现anonymous()方法调用错误
     * 但是调用这个方法时，首先出现了登录界面
     * 然后显示访问拒绝，用户不是匿名用户
     */
    @GetMapping("/anonymous")
    @PreAuthorize("anonymous")
    public String anonymous(){
        return "PreAuthorize注解的方法，只有匿名用户可以访问";
    }

    /**
     * authenticated表达式也不需要()
     */
    @GetMapping("/authenticated")
    @PreAuthorize("authenticated")
    public String authenticated(){
        return "PreAuthorize注解的方法，只有认证用户可以访问";
    }

    @GetMapping("/user")
    @PreAuthorize("hasRole('USER')")
    public String user(){
        return "PreAuthorize注解的方法，只有USER角色可以访问";
    }

    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String admin(){
        return "PreAuthorize注解的方法，只有ADMIN角色可以访问";
    }

    @GetMapping("/or/role")
    @PreAuthorize("hasAnyRole('ADMIN','USER')")
    public String anyRole(){
        return "PreAuthorize注解的方法，只有指定角色之一可以访问";
    }

    /**
     * and代表同时满足左右条件，且不需要大写
     */
    @GetMapping("/and/role")
    @PreAuthorize("hasRole('ADMIN') and hasRole('USER')")
    public String andRole(){
        return "PreAuthorize注解的方法，只有同时具有指定角色可以访问";
    }

    /**
     * denyAll()与permitAll()可以带括号
     */
    @GetMapping("/deny/all")
    @PreAuthorize("denyAll()")
    public String denyAll(){
        return "PreAuthorize注解的方法，拒绝任何用户的访问";
    }

    @GetMapping("/permit/all")
    @PreAuthorize("permitAll()")
    public String permitAll(){
        return "PreAuthorize注解的方法，允许任何用户的访问";
    }

    @GetMapping("/hehe")
    public String hehe(){
        return "这个方法没有注解，使用类注解";
    }

}
